/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package GISPackage;

import CCPVSimulationPackage.CCPVSimulation;
import java.awt.Color;
import java.io.File;
import java.util.Vector;

/**
 *
 * @author Heather
 */
public class Region
{

  public String name = "";
  public Vector<Integer> polygons = new Vector<Integer>();
  public File statisticsFile = null;
  public File altruismFileDirectory = null;
  public Color regionColor = null;
  public int numberOfFactorsForI = 4;
  public int numberOfFactorsForC = 4;
  public int numberOfFactorsForLambda = 5;
  public int numberOfFactorsForF = 1;
  public int averageIncome;
  public double percentageGrowthGDP;
  public double percentPoverty;
  public double lifeExpectancy;
  public double infancyMortalityRate;
  public double percentLiteracy;
  public double education;
  public int regimeType;
  public int regimeInstitution;
  public int regimeLegitimacy;
  public int regimeInstability;
  public int stateFragility;
  public int population;
  public double percentUrbanPopulation;
  public int landArea;
  public boolean mountainousTerrain;
  public static int maxLegitimacy = Integer.MIN_VALUE;
  public static int maxInstability = Integer.MIN_VALUE;
  public static int maxFragility = Integer.MIN_VALUE;
  public static int maxPopulation = Integer.MIN_VALUE;
  public static double maxUrbanPopulation = Double.MIN_VALUE;
  public static int maxLandArea = Integer.MIN_VALUE;
  public static double maxLifeExpectancy = Double.MIN_VALUE;
  public static double maxInfancyMortalityRate = Double.MIN_VALUE;
  public static double maxLiteracy = Double.MIN_VALUE;
  public static double maxEducation = Double.MIN_VALUE;
  public static double maxPoverty = Double.MIN_VALUE;
  public static double maxGrowthGDP = Double.MIN_VALUE;
  public double I;
  public double c;
  public double lambda;
  public double F;
  public boolean containsInvalidVariables = false;
  private static boolean maxValuesSet = false;

  public Region(String name, Vector<Integer> polygons, File statisticsFile, File altruismFileDirectory, Color regionColor)
  {
    this.name = name;
    this.polygons = polygons;
    this.statisticsFile = statisticsFile;
    this.altruismFileDirectory = altruismFileDirectory;
    this.regionColor = regionColor;
  }

  // returns true if the polygon of input index is contained in the region
  public boolean containsIndex(int index)
  {
    for (int i : polygons)
    {
      if (i == index)
      {
        return true;
      }
    }

    return false;
  }

  public boolean isSameRegion(Vector<Integer> other)
  {
    if (other.size() != polygons.size())
    {
      return false;
    }

    for (int i = 0; i < polygons.size(); i++)
    {
      if (other.get(i) != polygons.get(i))
      {
        return false;
      }
    }

    return true;
  }

  public static void setMaxValues(int maxLegitimacy,
          int maxInstability,
          int maxFragility,
          int maxPopulation,
          double maxUrbanPopulation,
          int maxLandArea,
          double maxLifeExpectancy,
          double maxInfancyMortalityRate,
          double maxLiteracy,
          double maxEducation,
          double maxPoverty,
          double maxGrowthGDP)
  {
    Region.maxLegitimacy = maxLegitimacy;
    Region.maxInstability = maxInstability;
    Region.maxFragility = maxFragility;
    Region.maxPopulation = maxPopulation;
    Region.maxUrbanPopulation = maxUrbanPopulation;
    Region.maxLandArea = maxLandArea;
    Region.maxLifeExpectancy = maxLifeExpectancy;
    Region.maxInfancyMortalityRate = maxInfancyMortalityRate;
    Region.maxLiteracy = maxLiteracy;
    Region.maxEducation = maxEducation;
    Region.maxPoverty = maxPoverty;
    Region.maxGrowthGDP = maxGrowthGDP;

    maxValuesSet = true;
  }

  public void setStructuralVariables(int averageIncome,
          double percentageGrowthGDP,
          double percentPoverty,
          double lifeExpectancy,
          double infancyMortalityRate,
          double percentLiteracy,
          double education,
          int regimeType,
          int regimeInstitution,
          int regimeLegitimacy,
          int regimeInstability,
          int stateFragility,
          int population,
          double percentUrbanPopulation,
          int landArea,
          boolean mountainousTerrain,
          int numberOfFactorsForI,
          int numberOfFactorsForC,
          int numberOfFactorsForLambda,
          int numberOfFactorsForF)
  {
    this.averageIncome = averageIncome;
    this.percentageGrowthGDP = percentageGrowthGDP;
    this.percentPoverty = percentPoverty;
    this.lifeExpectancy = lifeExpectancy;
    this.infancyMortalityRate = infancyMortalityRate;
    this.percentLiteracy = percentLiteracy;
    this.education = education;
    this.regimeType = regimeType;
    this.regimeInstitution = regimeInstitution;
    this.regimeLegitimacy = regimeLegitimacy;
    this.regimeInstability = regimeInstability;
    this.stateFragility = stateFragility;
    this.population = population;
    this.percentUrbanPopulation = percentUrbanPopulation;
    this.landArea = landArea;
    this.mountainousTerrain = mountainousTerrain;

    this.numberOfFactorsForI = numberOfFactorsForI;
    this.numberOfFactorsForC = numberOfFactorsForC;
    this.numberOfFactorsForLambda = numberOfFactorsForLambda;
    this.numberOfFactorsForF = numberOfFactorsForF;

    calculateAndSetAllStructuralVariables();
  }

  public void calculateAndSetAllStructuralVariables()
  {
    if (maxValuesSet)
    {
      calculateAndSetI(regimeType, regimeInstitution, regimeLegitimacy, regimeInstability, stateFragility);
      calculateAndSetc(population, percentUrbanPopulation, landArea, mountainousTerrain);
      calculateAndSetLambda(percentPoverty, lifeExpectancy, infancyMortalityRate, percentLiteracy, education);
      calculateAndSetF(percentageGrowthGDP);
    }
    else
    {
      //System.out.println("MAX VALUES ARE NOT SET.  REGION STRUCTURE VARIABLES ARE NOT SET.");
    }
  }

  private void calculateAndSetI(int regimeType,
          int regimeInstitution,
          int regimeLegitimacy,
          int regimeInstability,
          int stateFragility)
  {
    double total = regimeInstitution +
            (double) (regimeLegitimacy / (double) maxLegitimacy) +
            (double) (1-(regimeInstability / (double) maxInstability)) +
            (double) (1-(stateFragility / (double) maxFragility));

    if (numberOfFactorsForI > 0)
    {
      I = total / (double) numberOfFactorsForI;
    }
    else
    {
      I = 0;
      containsInvalidVariables = true;
    }
  }

  private void calculateAndSetc(int population,
          double percentUrbanPopulation,
          int landArea,
          boolean mountainousTerrain)
  {
    double total = (double) (1-(population / (double) maxPopulation)) +
            (double) (1-(percentUrbanPopulation / (double) maxUrbanPopulation)) +
            (double) (landArea / (double) maxLandArea);
    if (mountainousTerrain)
    {
      total++;
    }

    if (numberOfFactorsForC > 0)
    {
      c = total / (double) numberOfFactorsForC;
    }
    else
    {
      c = 0;
      containsInvalidVariables = true;
    }
  }

  private void calculateAndSetLambda(double percentPoverty,
          double lifeExpectancy,
          double infancyMortalityRate,
          double percentLiteracy,
          double education)
  {
    double total = (double) (percentPoverty / (double) maxPoverty) +
            (double) (1-(lifeExpectancy / (double) maxLifeExpectancy)) +
            (double) (infancyMortalityRate / (double) maxInfancyMortalityRate) +
            (double) (1-(percentLiteracy / (double) maxLiteracy)) +
            (double) (1-(education / (double) maxEducation));


    if (numberOfFactorsForLambda > 0)
    {
      lambda = total / numberOfFactorsForLambda;
    }
    else
    {
      lambda = 0;
      containsInvalidVariables = true;
    }
  }

  private void calculateAndSetF(double percentageGrowthGDP)
  {
    double total = percentageGrowthGDP / maxGrowthGDP;

    if (numberOfFactorsForF > 0)
    {
      F = total / numberOfFactorsForF;
    }
    else
    {
      F = 0;
      containsInvalidVariables = true;
    }
  }

  public String toString()
  {
    String ret = "";
    ret += "Name: " + name + "\n";
    ret += "Polygons: ";
    for (int i = 0; i < polygons.size() - 1; i++)
    {
      ret += polygons.get(i) + ", ";
    }
    ret += polygons.get(polygons.size() - 1) + "\n";

    ret += "Stats file: " + statisticsFile.getAbsolutePath() + "\n";
    ret += "Altruism file directory: " + altruismFileDirectory.getAbsolutePath() + "\n";
    ret += "Color: " + regionColor.getRed() + ", " + regionColor.getGreen() + ", " + regionColor.getBlue() + "\n";

    ret += "numberOfFactorsForI: " + numberOfFactorsForI + "\n";
    ret += "numberOfFactorsForC: " + numberOfFactorsForC + "\n";
    ret += "numberOfFactorsForLambda: " + numberOfFactorsForLambda + "\n";
    ret += "numberOfFactorsForF: " + numberOfFactorsForF + "\n";
    ret += "averageIncome: " + averageIncome + "\n";
    ret += "percentageGrowthGDP: " + percentageGrowthGDP + "\n";
    ret += "percentPoverty: " + percentPoverty + "\n";
    ret += "lifeExpectancy: " + lifeExpectancy + "\n";
    ret += "infancyMortalityRate: " + infancyMortalityRate + "\n";
    ret += "percentLiteracy: " + percentLiteracy + "\n";
    ret += "education: " + education + "\n";
    ret += "regimeType: " + regimeType + "\n";
    ret += "regimeInstitution: " + regimeInstitution + "\n";
    ret += "regimeLegitimacy: " + regimeLegitimacy + "\n";
    ret += "regimeInstability: " + regimeInstability + "\n";
    ret += "stateFragility: " + stateFragility + "\n";
    ret += "population: " + population + "\n";
    ret += "percentUrbanPopulation: " + percentUrbanPopulation + "\n";
    ret += "landArea: " + landArea + "\n";
    ret += "mountainousTerrain: " + mountainousTerrain + "\n";
    ret += "maxLegitimacy: " + maxLegitimacy + "\n";
    ret += "maxInstability: " + maxInstability + "\n";
    ret += "maxFragility: " + maxFragility + "\n";
    ret += "maxPopulation: " + maxPopulation + "\n";
    ret += "maxUrbanPopulation: " + maxUrbanPopulation + "\n";
    ret += "maxLandArea: " + maxLandArea + "\n";
    ret += "maxLifeExpectancy: " + maxLifeExpectancy + "\n";
    ret += "maxInfancyMortalityRate: " + maxInfancyMortalityRate + "\n";
    ret += "maxLiteracy: " + maxLiteracy + "\n";
    ret += "maxEducation: " + maxEducation + "\n";
    ret += "maxPoverty: " + maxPoverty + "\n";
    ret += "maxGrowthGDP: " + maxGrowthGDP + "\n";
    ret += "I: " + I + "\n";
    ret += "c: " + c + "\n";
    ret += "lambda: " + lambda + "\n";
    ret += "F: " + F + "\n";
    ret += "maxValuesSet: " + maxValuesSet + "\n";

    return ret;
  }
}
